package com.uxsino.simo.collector.connections;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jcraft.jsch.SftpException;
import com.uxsino.commons.io.IO;
import com.uxsino.simo.connections.exception.SimoConnectionException;
import com.uxsino.simo.connections.exception.SimoQueryException;
import com.uxsino.simo.connections.target.SSHFileTarget;
import com.uxsino.simo.connections.target.TCPTarget;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;

/**
 * @see SSHFileDownloadConnection
 */
public class SSHFileConnection extends AbstractSFTPConnection<SSHFileTarget> {

    private static Logger logger = LoggerFactory.getLogger(SSHFileConnection.class);

    protected String[] filePaths;

    private int threshold = 5 * 1024 * 1024;

    public SSHFileConnection() {
        super();
    }

    @Override
    public int connect(TCPTarget target) {
        SSHFileTarget t = (SSHFileTarget) target;
        filePaths = t.getFiles().split(",");
        for (int i = 0; i < filePaths.length; i++) {
            filePaths[i] = filePaths[i].trim();
        }
        return super.connect(target);
    }

    @Override
    public Object execCmd(Object cmdPattern) throws SimoQueryException, SimoConnectionException {
        JSONArray result = new JSONArray();
        for (int i = 0; i < filePaths.length; i++) {
            try (InputStream is = download(".", filePaths[i])) {
                if (is == null) {
                    logger.error("can't read file {}", filePaths[i]);
                } else {
                    ByteArrayOutputStream aos = IO.read(is);
                    int size = aos.size();
                    if (size > threshold) {
                        logger.warn("The size of {} is {}, more than {}", filePaths[i], size, threshold);
                    }
                    JSONObject o = new JSONObject();
                    o.put("path", filePaths[i]);
                    o.put("content", aos.toString());
                    result.add(o);
                }
            } catch (Exception e){
                logger.error("read file " + filePaths[i] + " error", e);
            }
        }
        return result;
    }

    @Override
    public int supportedFeatures() {
        return F_DOWNLOAD;
    }

    @Override
    public boolean upload(String remotePath, String fileName, InputStream fileToUpload) {
        return false;
    }

    @Override
    public InputStream download(String remotePath, String fileName) throws SimoConnectionException {
        try {
            channelSftp.cd(remotePath);
            return channelSftp.get(fileName);
        } catch (SftpException e) {
            logger.error("error download file, path {}, file name {} ", remotePath, fileName, e);
            throw new SimoConnectionException(e);
        }

    }

}
